﻿using MongoDB.Bson;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Sustainalytics.Reporting.BusinessLogic
{
    public class RepositoryCollectionAsync<T> : RepositoryCollectionAsync<T, Guid>, IRepositoryCollectionAsync<T> where T : IEntity<Guid>
    {
        public RepositoryCollectionAsync(string connectionString)
            : base(connectionString) { }

    }

    public class RepositoryCollectionAsync<TDocument, TKey> : IRepositoryCollectionAsync<TDocument, TKey> where TDocument : IEntity<TKey>
    {
        protected internal IMongoCollection<TDocument> collection;

        public IMongoCollection<TDocument> Collection
        {
            get { return collection; }
        }

        public RepositoryCollectionAsync(string connectionString)
        {
            var url = new MongoUrl(connectionString);
            //var client = new MongoClient(url);
            var client = new MongoClient(new MongoClientSettings
            {
                MaxConnectionPoolSize = 10000,
                Server = url.Server
            });

            var database = client.GetDatabase(url.DatabaseName);

            collection = database.GetCollection<TDocument>(typeof(TDocument).Name);
 
        }

        public async Task Save(TDocument document, Guid id, CancellationToken cancellationToken = default(CancellationToken))
        {
            var filter = Builders<TDocument>.Filter.Eq("Id", id);

            var options = new FindOneAndReplaceOptions<TDocument>() { IsUpsert = true };

            var result = await collection.FindOneAndReplaceAsync(filter, document, options, cancellationToken);
        }

        public async Task BulkInsert(IEnumerable<TDocument> documents, CancellationToken cancellationToken = default(CancellationToken))
        {
            //new BsonDocument("_id", document.Id)
            var updates = documents.Select(document => new ReplaceOneModel<TDocument>(
                Builders<TDocument>.Filter.Eq("_id", document.Id), document) { IsUpsert = true });
            //, new UpdateOptions { IsUpsert = true })
            await collection.BulkWriteAsync(updates, cancellationToken: cancellationToken);
        }
    }
}
